home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 26
/
Cream of the Crop 26.iso
/
program
/
ccdl151s.zip
/
SOURCE
/
ARGS.C
< prev
next >
Wrap
C/C++ Source or Header
|
1997-03-15
|
5KB
|
179 lines
/*
* 68K/386 32-bit C compiler.
*
* copyright (c) 1997, David Lindauer
*
* This compiler is intended for educational use. It may not be used
* for profit without the express written consent of the author.
*
* It may be freely redistributed, as long as this notice remains intact
* and either the original sources or derived sources
* are distributed along with any executables derived from the originals.
*
* The author is not responsible for any damages that may arise from use
* of this software, either idirect or consequential.
*
* v1.35 March 1997
* David Lindauer, gclind01@starbase.spd.louisville.edu
*
* Credits to Mathew Brandt for original K&R C compiler
*
*/
#include <stdio.h>
#include <ctype.h>
#include "cmdline.h"
/*
* This module handles command line arguments. The main program defines
* an array specifying what arguments are allowed and what the activity
* should be for each argument and then calls parse_args giving it
* argv and argc as arguments. Parse-args dispatches any arguments it
* finds to the action routine and then deletes the argument it found
* from argv[]
*/
/*
* The main program must define this array. It customizes the types of
* arguments that will be allowed
*
*/
extern ARGLIST ArgList[];
static BOOL use_case; /* Gets set for case sensitivity */
/*
* Function that unlinks the argument from che argv[] chain
*/
static void remove_arg(int pos, int *count, char *list[])
{
int i;
/* Decrement length of list */
(*count)--;
/* move items down */
for (i=pos; i<*count; i++)
list[i] = list[i+1];
}
/*
* ompare two characters, ignoring case if necessary
*/
static BOOL cmatch(char t1, char t2)
{
if (use_case)
return(t1 == t2);
return(toupper(t1) == toupper(t2));
}
/* Routine scans a string to see if any of the characters match
* the arguments, then dispatches to the action routine if so.
*/
/* Callbacks of the form
* void boolcallback( char selectchar, BOOL value)
* void switchcallback( char selectchar, BOOL value) ;; value always true
* void stringcallback( char selectchar, char *string)
*/
static int scan_args(char *string, int index, char *arg)
{
int i=-1;
while (ArgList[++i].id) {
switch( ArgList[i].mode) {
case ARG_SWITCHSTRING:
if (cmatch(string[index], ArgList[i].id)) {
(* ArgList[i].routine)(string[index],&string[index]);
return (ARG_NEXTCHAR);
}
break;
case ARG_SWITCH:
if (cmatch(string[index], ArgList[i].id)) {
(* ArgList[i].routine)(string[index],(char *)TRUE);
return (ARG_NEXTCHAR);
}
break;
case ARG_BOOL:
if (cmatch(string[index], ArgList[i].id)) {
if (string[0] == ARG_SEPTRUE)
(* ArgList[i].routine)(string[index],(char *)TRUE);
else
(* ArgList[i].routine)(string[index],(char *)FALSE);
return(ARG_NEXTCHAR);
}
break;
case ARG_CONCATSTRING:
if (cmatch(string[index], ArgList[i].id)) {
(* ArgList[i].routine)(string[index], string+index+1);
return(ARG_NEXTARG);
}
break;
case ARG_NOCONCATSTRING:
if (cmatch(string[index], ArgList[i].id)) {
if (!arg)
return(ARG_NOARG);
(* ArgList[i].routine)(string[index], arg);
return(ARG_NEXTNOCAT);
}
break;
}
}
return(ARG_NOMATCH);
}
/*
* Main parse routine. Scans for '-', then scan for arguments and
* delete from the argv[] array if so.
*/
BOOL parse_args(int *argc, char *argv[], BOOL case_sensitive)
{
int pos = 0;
BOOL retval = TRUE;
use_case = case_sensitive;
while(++pos < *argc) {
if ((argv[pos][0] == ARG_SEPSWITCH) || (argv[pos][0] == ARG_SEPFALSE)
|| (argv[pos][0] == ARG_SEPTRUE)) {
int argmode;
int index = 1;
int done = FALSE;
do {
/* Scan the present arg */
if (pos < *argc - 1)
argmode = scan_args(argv[pos], index, argv[pos+1]);
else
argmode = scan_args(argv[pos], index, 0);
switch(argmode) {
case ARG_NEXTCHAR:
/* If it was a char, go to the next one */
if (!argv[pos][++index])
done = TRUE;
break;
case ARG_NEXTNOCAT:
/* Otherwise if it was a nocat, remove the extra arg */
remove_arg(pos, argc, argv);
/* Fall through to NEXTARG */
case ARG_NEXTARG:
/* Just a next arg, go do it */
done = TRUE;
break;
case ARG_NOMATCH:
/* No such arg, spit an error */
fprintf(stderr,"Invalid Arg: %s\n", argv[pos]);
done = TRUE;
retval = FALSE;
break;
case ARG_NOARG:
/* Missing the arg for a CONCAT type, spit the error */
fprintf(stderr,"Missing string for Arg %s\n", argv[pos]);
done = TRUE;
retval = FALSE;
break;
};
} while (!done);
/* We'll always get rid of the present arg
* And back up one
*/
remove_arg(pos--, argc, argv);
}
}
return(retval);
}